home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / os2 / gnuwget.zip / wget-1.4.3 / src / mtch.c < prev    next >
C/C++ Source or Header  |  1997-01-19  |  5KB  |  197 lines

  1. /* Globbing routines, originally a part of GNU bash
  2.    Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
  3.    
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.    
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.    
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18.  
  19. #ifdef HAVE_CONFIG_H
  20. #  include <config.h>
  21. #endif /* HAVE_CONFIG_H */
  22.  
  23. #include <errno.h>
  24. #include "wget.h"
  25. #include "mtch.h"
  26.  
  27. /* Match STRING against the filename pattern PATTERN, returning zero
  28.    if it matches, FNM_NOMATCH if not.  */
  29. int
  30. fnmatch (const char *pattern, const char *string, int flags)
  31. {
  32.    register const char *p = pattern, *n = string;
  33.    register char c;
  34.    
  35.    if ((flags & ~__FNM_FLAGS) != 0)
  36.    {
  37.       errno = EINVAL;
  38.       return (-1);
  39.    }
  40.    
  41.    while ((c = *p++) != '\0')
  42.    {
  43.       switch (c)
  44.       {
  45.      case '?':
  46.         if (*n == '\0')
  47.            return (FNM_NOMATCH);
  48.         else if ((flags & FNM_PATHNAME) && *n == '/')
  49.            return (FNM_NOMATCH);
  50.         else if ((flags & FNM_PERIOD) && *n == '.' &&
  51.              (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  52.            return (FNM_NOMATCH);
  53.         break;
  54.         
  55.      case '\\':
  56.         if (!(flags & FNM_NOESCAPE))
  57.            c = *p++;
  58.         if (*n != c)
  59.            return (FNM_NOMATCH);
  60.         break;
  61.  
  62.      case '*':
  63.         if ((flags & FNM_PERIOD) && *n == '.' &&
  64.         (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  65.            return (FNM_NOMATCH);
  66.         
  67.         for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  68.            if (((flags & FNM_PATHNAME) && *n == '/') ||
  69.            (c == '?' && *n == '\0'))
  70.           return (FNM_NOMATCH);
  71.  
  72.         if (c == '\0')
  73.            return (0);
  74.         
  75.         {
  76.            char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  77.            for (--p; *n != '\0'; ++n)
  78.           if ((c == '[' || *n == c1) &&
  79.               fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
  80.              return (0);
  81.            return (FNM_NOMATCH);
  82.         }
  83.         
  84.      case '[':
  85.         {
  86.            /* Nonzero if the sense of the character class is
  87.           inverted.  */
  88.            register int not;
  89.            
  90.            if (*n == '\0')
  91.           return (FNM_NOMATCH);
  92.  
  93.            if ((flags & FNM_PERIOD) && *n == '.' &&
  94.            (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  95.           return (FNM_NOMATCH);
  96.  
  97.            /* Make sure there is a closing `]'.  If there isn't,
  98.           the `[' is just a character to be matched. */
  99.            {
  100.           register const char *np;
  101.  
  102.           for (np = p; np && *np && *np != ']'; np++);
  103.           
  104.           if (np && !*np)
  105.           {
  106.              if (*n != '[')
  107.             return (FNM_NOMATCH);
  108.              goto next_char;
  109.           }
  110.            }
  111.           
  112.            not = (*p == '!' || *p == '^');
  113.            if (not)
  114.           ++p;
  115.  
  116.            c = *p++;
  117.            for (;;)
  118.            {
  119.           register char cstart = c, cend = c;
  120.  
  121.           if (!(flags & FNM_NOESCAPE) && c == '\\')
  122.              cstart = cend = *p++;
  123.           
  124.           if (c == '\0')
  125.              /* [ (unterminated) loses.  */
  126.              return (FNM_NOMATCH);
  127.  
  128.           c = *p++;
  129.  
  130.           if ((flags & FNM_PATHNAME) && c == '/')
  131.              /* [/] can never match.  */
  132.              return (FNM_NOMATCH);
  133.  
  134.           if (c == '-' && *p != ']')
  135.           {
  136.              cend = *p++;
  137.              if (!(flags & FNM_NOESCAPE) && cend == '\\')
  138.             cend = *p++;
  139.              if (cend == '\0')
  140.             return (FNM_NOMATCH);
  141.              c = *p++;
  142.           }
  143.  
  144.           if (*n >= cstart && *n <= cend)
  145.              goto matched;
  146.  
  147.           if (c == ']')
  148.              break;
  149.            }
  150.            if (!not)
  151.           return (FNM_NOMATCH);
  152.  
  153.         next_char:
  154.            break;
  155.  
  156.         matched:
  157.            /* Skip the rest of the [...] that already matched.  */
  158.            while (c != ']')
  159.            {
  160.           if (c == '\0')
  161.              /* [... (unterminated) loses.  */
  162.              return (FNM_NOMATCH);
  163.           
  164.           c = *p++;
  165.           if (!(flags & FNM_NOESCAPE) && c == '\\')
  166.              /* 1003.2d11 is unclear if this is right.  %%% */
  167.              ++p;
  168.            }
  169.            if (not)
  170.           return (FNM_NOMATCH);
  171.         }
  172.         break;
  173.  
  174.      default:
  175.         if (c != *n)
  176.            return (FNM_NOMATCH);
  177.       }
  178.  
  179.       ++n;
  180.    }
  181.  
  182.    if (*n == '\0')
  183.       return (0);
  184.  
  185.    return (FNM_NOMATCH);
  186. }
  187.  
  188. /* Decide whether a string contains globbing wildcards. */
  189. int
  190. has_wildcards(const char *s)
  191. {
  192.    for (; *s; s++)
  193.       if (*s == '*' || *s == '?' || *s == '[' || *s == ']')
  194.      return 1;
  195.    return 0;
  196. }
  197.